package com.isoftstone.industry.aaa.core.service.accounting.charging.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.isoftstone.industry.common.util.CommonUtils;
import com.isoftstone.industry.persistance.bean.AppInstance;
import com.isoftstone.industry.persistance.bean.BillingList;
import com.isoftstone.industry.persistance.bean.ChargingItem;
import com.isoftstone.industry.persistance.bean.PricingInfo;
import com.isoftstone.industry.persistance.bean.PricingInfoSnapshot;
import com.isoftstone.industry.persistance.bean.ProductInstance;
import com.isoftstone.industry.persistance.bean.Tariff;
import com.isoftstone.industry.persistance.bean.TariffSnapshot;
import com.isoftstone.industry.persistance.bean.TicketInfo;
import com.isoftstone.industry.persistance.bean.Unit;
import com.isoftstone.industry.aaa.core.service.accounting.charging.IChargingEngine;
import com.isoftstone.industry.aaa.core.service.assist.IProductInstService;
import com.isoftstone.industry.aaa.core.service.assist.ITicketInfoService;
import com.isoftstone.modules.core.utils.DateUtils;

@Service("usageChargingEngine")
public class UsageChargingEngine  extends AbstractChargingEnginer implements IChargingEngine
{
	@Resource
	private ITicketInfoService ticketInfoService;
	
	@Resource
	private IProductInstService prodInstService;
	
	@Override
	public void charge4Postpaid()
	{
		PricingInfoSnapshot pricingInfoSnap = chargingItemDetail.getPricingInfoSnapshot();
		ChargingItem chargingItem = chargingItemDetail.getChargingItem();
		ProductInstance prodInst = chargingItem.getProdInst();
		// 2015-04产品包 start
		ArrayList<String> appInstIds = new ArrayList<String>();
		if(CommonUtils.isNotEmpty(prodInst.getSubProdInsts())){
			List<ProductInstance> subProdInsts = prodInst.getSubProdInsts();
			for(ProductInstance sub: subProdInsts){
				appInstIds.add(sub.getAppInstance().getId());
			}
		}else{
			appInstIds.add(prodInst.getAppInstance().getId());
		}
		// 2015-04产品包 end
		//AppInstance appInst = prodInst.getAppInstance();
		String calcMethod = pricingInfoSnap.getCalcMethod();
		Date chargingStartDate = billingCycle.getBeginDate();
		Date chargingEndDate = billingCycle.getEndDate();
		String measureMethod = pricingInfoSnap.getMeasureMethod();
		List<TariffSnapshot> tariffSnapList = pricingInfoSnap.getTariffList();
		TariffSnapshot tariffSnap = tariffSnapList.get(0);
		String tCalcMethod = tariffSnap.getCalcMethod();
		if(PricingInfo.ICalcMethod.DIRECT.equals(calcMethod)){
			//2015-04 产品包 获取ticketInfos
			List<TicketInfo> unchargedTickInfoList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, chargingStartDate, chargingEndDate);
			//List<TicketInfo> unchargedTickInfoList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, chargingStartDate, chargingEndDate);
			if(PricingInfo.IMeasureMethod.TIME_BASED.equals(measureMethod)||PricingInfo.IMeasureMethod.SMS_BASED.equals(measureMethod)){
				if(unchargedTickInfoList.size()>0){
					if(Tariff.ICalcMethod.DIRECT.equals(tCalcMethod)){
						double fixedPrice = tariffSnap.getFixedPrice();
						double uPrice = fixedPrice/tariffSnap.getMeasureRate();
						for(TicketInfo ticketInfo : unchargedTickInfoList){
							createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
									BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(chargingStartDate), DateUtils.createEndTime(chargingEndDate));
							ticketInfoService.markCharged(ticketInfo.getId());
						}
						chargingItemDetailService.changeLastChargingTime(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp());
					}else if(Tariff.ICalcMethod.TIMING_MEASURE_COMBINE.equals(tCalcMethod)){
						throw new UnsupportedOperationException("非法的计算方式，按次/短信条数计费不支持计时计量组合！");
					}
				}
			//按用户数计费
			}else if(PricingInfo.IMeasureMethod.USER_BASED.equals(measureMethod)){
				if(unchargedTickInfoList.size()>0){
					if(Tariff.ICalcMethod.DIRECT.equals(tCalcMethod)){
						double fixedPrice = tariffSnap.getFixedPrice();
						double uPrice = fixedPrice/tariffSnap.getMeasureRate();
						for(TicketInfo ticketInfo : unchargedTickInfoList){
							createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
									BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(chargingStartDate), DateUtils.createEndTime(chargingEndDate));
							ticketInfoService.markCharged(ticketInfo.getId());
						}
						chargingItemDetailService.changeLastChargingTime(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp());
					}else if(Tariff.ICalcMethod.TIMING_MEASURE_COMBINE.equals(tCalcMethod)){
						Unit timingUnit = tariffSnap.getTimingUnit();
						int timingRate = tariffSnap.getTimingRate().intValue();
						int measureRate = tariffSnap.getMeasureRate().intValue();
						String ucode = timingUnit.getCode();
						if(Unit.TimeUnit.MONTH.equals(ucode)){
							int m_interval = DateUtils.getIntervalMonths(chargingStartDate,chargingEndDate)+1;
							double fixedPrice = tariffSnap.getFixedPrice();
							double uPrice = fixedPrice/timingRate/measureRate * m_interval;
							for(TicketInfo ticketInfo : unchargedTickInfoList){
								createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
										BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(chargingStartDate), DateUtils.createEndTime(chargingEndDate));
								ticketInfoService.markCharged(ticketInfo.getId());
							}
						}else if(Unit.TimeUnit.YEAR.equals(ucode)){
							Date chargeEndDate = chargingItemDetail.getChargingEndDate();
							Date startDate = chargingItemDetail.getChargingItem().getEffDate();
							if(chargeEndDate != null){
								startDate = DateUtils.adjustByDay(chargeEndDate, 1);
							}
							Date endDate = DateUtils.adjustByDay(DateUtils.addYear(startDate, 1),-1);
							//判断是否达到了计费周期内
							if(!endDate.after(chargingEndDate)){
								//2015-04 产品包 获取ticketInfos
								unchargedTickInfoList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, startDate, endDate);
								//unchargedTickInfoList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, startDate, endDate);
								double fixedPrice = tariffSnap.getFixedPrice();
								double uPrice = fixedPrice/timingRate/measureRate;
								for(TicketInfo ticketInfo : unchargedTickInfoList){
									createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
											BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(startDate), DateUtils.createEndTime(endDate));
									ticketInfoService.markCharged(ticketInfo.getId());
								}
								chargingItemDetailService.changeLastChargingTimeAndChargingEndDate(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp(), endDate);
							}
						}else{
							throw new UnsupportedOperationException("非法的计费周期，计时计量组合目前只支持年、月");
						}
					}
				}
			}else{
				throw new UnsupportedOperationException("非法的计量模式，目前只支持按次、用户数、短信数计量方式！");
			}
		}else if(PricingInfo.ICalcMethod.TRAP.equals(calcMethod)){
			boolean needCharge = true;
			Date endDate = null; 
			if(PricingInfo.IMeasureMethod.TIME_BASED.equals(measureMethod)||PricingInfo.IMeasureMethod.SMS_BASED.equals(measureMethod) || (PricingInfo.IMeasureMethod.USER_BASED.equals(measureMethod) && Tariff.ICalcMethod.DIRECT.equals(tCalcMethod))){
				Date startDate = chargingStartDate;
				endDate = chargingEndDate;
				Date effDate = chargingItem.getEffDate();
				String mcType = pricingInfoSnap.getMcType();
				long chargedCount = 0;
				List<TicketInfo> unchargedTickekList = null;
				if(PricingInfo.IMcType.ALL.equals(mcType)){
					//2015-04 产品包 获取ticketInfos
					chargedCount = ticketInfoService.countCharged4All(appInstIds, measureMethod);
					unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, effDate, chargingEndDate);
					//chargedCount = ticketInfoService.countCharged4All(appInst.getId(), measureMethod);
					//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, effDate, chargingEndDate);
				}else if(PricingInfo.IMcType.MONTH_BASED.equals(mcType)){
					if(startDate.before(effDate)){
						startDate = effDate;
					}
					//2015-04 产品包 获取ticketInfos
					chargedCount = ticketInfoService.countCharged4Between(appInstIds, measureMethod, startDate, endDate);
					unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, startDate,endDate);
					//chargedCount = ticketInfoService.countCharged4Between(appInst.getId(), measureMethod, startDate, endDate);
					//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, startDate,endDate);
				}else if(PricingInfo.IMcType.YEAR_BASED.equals(mcType)){
					Date chargeEndDate = chargingItemDetail.getChargingEndDate();
					startDate = chargingItem.getEffDate();
					if(chargeEndDate != null){
						startDate = DateUtils.adjustByDay(chargeEndDate, 1);
					}
					endDate = DateUtils.adjustByDay(DateUtils.addYear(startDate, 1),-1);
					//判断是否达到了计费周期内
					if(!endDate.after(chargingEndDate)){
						//2015-04 产品包 获取ticketInfos
						chargedCount = ticketInfoService.countCharged4Between(appInstIds, measureMethod, startDate, endDate);
						unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, startDate, endDate);
						//chargedCount = ticketInfoService.countCharged4Between(appInst.getId(), measureMethod, startDate, endDate);
						//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, startDate, endDate);
					}else{
						needCharge = false;
					}
				}else{
					throw new UnsupportedOperationException("非法的计量统计方式，阶梯型计算方式只支持全部、按月、按年统计！");
				}
				if(needCharge){
					if(unchargedTickekList != null && unchargedTickekList.size()>0){
						double uPrice = getPrice4Trap(tariffSnapList, unchargedTickekList.size());
						for(TicketInfo ticketInfo : unchargedTickekList){
							long chargeOrder = chargedCount + 1;
							createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
									BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(startDate), DateUtils.createEndTime(endDate));
							ticketInfoService.markCharged(ticketInfo.getId(), chargeOrder);
							chargedCount++ ;
						}
						if(PricingInfo.IMcType.YEAR_BASED.equals(mcType)){
							chargingItemDetailService.changeLastChargingTimeAndChargingEndDate(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp(), endDate);
						}else{
							chargingItemDetailService.changeLastChargingTime(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp());
						}
					}
				}
			}else if(PricingInfo.IMeasureMethod.USER_BASED.equals(measureMethod) && Tariff.ICalcMethod.TIMING_MEASURE_COMBINE.equals(tCalcMethod)){
				String mcType = pricingInfoSnap.getMcType();
				Unit timingUnit = tariffSnap.getTimingUnit();
				String ucode = timingUnit.getCode();
				long chargedCount = 0;
				List<TicketInfo> unchargedTickekList = null;
				if(PricingInfo.IMcType.ALL.equals(mcType)){
					if(Unit.TimeUnit.YEAR.equals(ucode)){
						Date chargeEndDate = chargingItemDetail.getChargingEndDate();
						Date startDate = chargingItemDetail.getChargingItem().getEffDate();
						if(chargeEndDate != null){
							startDate = DateUtils.adjustByDay(chargeEndDate, 1);
						}
						endDate = DateUtils.adjustByDay(DateUtils.addYear(startDate, 1),-1);
						//判断是否达到了计费周期内
						if(!endDate.after(chargingEndDate)){
							//2015-04 产品包 获取ticketInfos
							chargedCount = ticketInfoService.countCharged4All(appInstIds, measureMethod);
							unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, startDate, endDate);
							//chargedCount = ticketInfoService.countCharged4All(appInst.getId(), measureMethod);
							//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, startDate, endDate);
							for(TicketInfo ticketInfo : unchargedTickekList){
								long chargeOrder = chargedCount + 1;
								double uPrice = getPrice4Trap(tariffSnapList, chargeOrder);
								createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
										BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(startDate), DateUtils.createEndTime(endDate));
								ticketInfoService.markCharged(ticketInfo.getId(), chargeOrder);
								chargedCount++ ;
							}
							chargingItemDetailService.changeLastChargingTimeAndChargingEndDate(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp(), endDate);
						}
					}else if(Unit.TimeUnit.MONTH.equals(ucode)){
						//2015-04 产品包 获取ticketInfos
						chargedCount = ticketInfoService.countCharged4All(appInstIds, measureMethod);
						unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, chargingStartDate, chargingEndDate);
						//chargedCount = ticketInfoService.countCharged4All(appInst.getId(), measureMethod);
						//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, chargingStartDate, chargingEndDate);
						for(TicketInfo ticketInfo : unchargedTickekList){
							long chargeOrder = chargedCount + 1;
							double uPrice = getPrice4Trap(tariffSnapList, chargeOrder);
							createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
									BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(chargingStartDate), DateUtils.createEndTime(chargingEndDate));
							ticketInfoService.markCharged(ticketInfo.getId(), chargeOrder);
							chargedCount++ ;
						}
						chargingItemDetailService.changeLastChargingTime(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp());
					}else{
						throw new UnsupportedOperationException("非法的计费周期，计时计量组合目前只支持年、月");
					}
				}else if(PricingInfo.IMcType.YEAR_BASED.equals(mcType)){
					Date chargeEndDate = chargingItemDetail.getChargingEndDate();
					Date startDate = chargingItem.getEffDate();
					if(chargeEndDate != null){
						startDate = DateUtils.adjustByDay(chargeEndDate, 1);
					}
					endDate = DateUtils.adjustByDay(DateUtils.addYear(startDate, 1),-1);
					//判断是否达到了计费周期内
					if(!endDate.after(chargingEndDate)){
						//2015-04 产品包 获取ticketInfos
						chargedCount = ticketInfoService.countCharged4Between(appInstIds, measureMethod, startDate, endDate);
						unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, startDate, endDate);
						//chargedCount = ticketInfoService.countCharged4Between(appInst.getId(), measureMethod, startDate, endDate);
						//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, startDate, endDate);
						for(TicketInfo ticketInfo : unchargedTickekList){
							long chargeOrder = chargedCount + 1;
							double uPrice = getPrice4Trap(tariffSnapList, chargeOrder);
							if(Unit.TimeUnit.MONTH.equals(ucode)){
								uPrice = uPrice *12;
							}
							createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
									BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(startDate), DateUtils.createEndTime(endDate));
							ticketInfoService.markCharged(ticketInfo.getId(), chargeOrder);
							chargedCount++ ;
						}
						chargingItemDetailService.changeLastChargingTimeAndChargingEndDate(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp(), endDate);
					}
				}else if(PricingInfo.IMcType.MONTH_BASED.equals(mcType)){
					if(Unit.TimeUnit.MONTH.equals(ucode)){
						//2015-04 产品包 获取ticketInfos
						chargedCount = ticketInfoService.countCharged4Between(appInstIds, measureMethod, chargingStartDate, chargingEndDate);
						unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, chargingStartDate, chargingEndDate);
						//chargedCount = ticketInfoService.countCharged4Between(appInst.getId(), measureMethod, chargingStartDate, chargingEndDate);
						//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, chargingStartDate, chargingEndDate);
						for(TicketInfo ticketInfo : unchargedTickekList){
							long chargeOrder = chargedCount + 1;
							double uPrice = getPrice4Trap(tariffSnapList, chargeOrder);
							createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
									BillingList.Type.POST_USAGE, uPrice, null, ticketInfo, DateUtils.createStartTime(chargingStartDate), DateUtils.createEndTime(chargingEndDate));
							ticketInfoService.markCharged(ticketInfo.getId(), chargeOrder);
							chargedCount++ ;
						}
						chargingItemDetailService.changeLastChargingTime(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp());
					}else{
						throw new UnsupportedOperationException("非法的计时计量组合模式，月统计方式只支持按月计时模式！");
					}
				}else{
					throw new UnsupportedOperationException("非法的计量统计方式，阶梯型计算方式只支持全部、按月、按年统计！");
				}
			}else{
				throw new UnsupportedOperationException("非法的计量模式，目前只支持按次、用户数、短信数计量方式！");
			}
		}else{
			throw new UnsupportedOperationException("非法的计费模式，使用量计费不支持离散型计算方法！");
		}
	}

	@Override
	public void charge4Prepaid()
	{
		PricingInfoSnapshot pricingInfoSnap = chargingItemDetail.getPricingInfoSnapshot();
		ChargingItem chargingItem = chargingItemDetail.getChargingItem();
		ProductInstance prodInst = chargingItem.getProdInst();
		
		// 2015-04产品包 start
		ArrayList<String> appInstIds = new ArrayList<String>();
		if(CommonUtils.isNotEmpty(prodInst.getSubProdInsts())){
			List<ProductInstance> subProdInsts = prodInst.getSubProdInsts();
			for(ProductInstance sub: subProdInsts){
				appInstIds.add(sub.getAppInstance().getId());
			}
		}else{
			appInstIds.add(prodInst.getAppInstance().getId());
		}
		// 2015-04产品包 end
		//AppInstance appInst = prodInst.getAppInstance();
		String calcMethod = pricingInfoSnap.getCalcMethod();
		String measureMethod = pricingInfoSnap.getMeasureMethod();
		if(PricingInfo.ICalcMethod.DIRECT.equals(calcMethod)){
			TariffSnapshot tariffSnap = pricingInfoSnap.getTariffList().get(0);
			//按次计费或短信数计费
			if(PricingInfo.IMeasureMethod.TIME_BASED.equals(measureMethod)||PricingInfo.IMeasureMethod.SMS_BASED.equals(measureMethod)){
				//2015-04 产品包 获取ticketInfos
				List<TicketInfo> unchargedTickInfoList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeMode(appInstIds, measureMethod);
				//List<TicketInfo> unchargedTickInfoList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeMode(appInst.getId(), measureMethod);
				if(unchargedTickInfoList.size()>0){
					String tCalcMethod = tariffSnap.getCalcMethod();
					if(Tariff.ICalcMethod.DIRECT.equals(tCalcMethod)){
						double fixedPrice = tariffSnap.getFixedPrice();
						double uPrice = fixedPrice/tariffSnap.getMeasureRate();
						for(TicketInfo ticketInfo : unchargedTickInfoList){
							createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
									BillingList.Type.PRE_USAGE, uPrice, null, ticketInfo, null, null);
							ticketInfoService.markCharged(ticketInfo.getId());
						}
						chargingItemDetailService.changeLastChargingTime(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp());
					}else if(Tariff.ICalcMethod.TIMING_MEASURE_COMBINE.equals(tCalcMethod)){
						throw new UnsupportedOperationException("非法的计算方式，按次/短信条数计费不支持计时计量组合！");
					}
				}
			//按用户数计费
			}else if(PricingInfo.IMeasureMethod.USER_BASED.equals(measureMethod)){
				//2015-04 产品包 获取ticketInfos
				List<TicketInfo> unchargedTickInfoList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeMode(appInstIds, PricingInfo.IMeasureMethod.USER_BASED);
				//List<TicketInfo> unchargedTickInfoList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeMode(appInst.getId(), PricingInfo.IMeasureMethod.USER_BASED);
				if(unchargedTickInfoList.size()>0){
					double fixedPrice = tariffSnap.getFixedPrice();
					double uPrice = fixedPrice/tariffSnap.getMeasureRate();
					for(TicketInfo ticketInfo : unchargedTickInfoList){
						createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
								BillingList.Type.PRE_USAGE, uPrice, null, ticketInfo, null, null);
						ticketInfoService.markCharged(ticketInfo.getId());
					}
					chargingItemDetailService.changeLastChargingTime(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp());
				}
			}else{
				throw new UnsupportedOperationException("非法的计量模式，目前只支持按次、用户数、短信数计量方式！");
			}
		}else if(PricingInfo.ICalcMethod.TRAP.equals(calcMethod)){
			Date today = DateUtils.today();
			Date effDate = chargingItem.getEffDate();
			String mcType = pricingInfoSnap.getMcType();
			long chargedCount = 0;
			List<TicketInfo> unchargedTickekList = null;
			if(PricingInfo.IMcType.ALL.equals(mcType)){
				//2015-04 产品包 获取ticketInfos
				chargedCount = ticketInfoService.countCharged4All(appInstIds, measureMethod);
				unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeMode(appInstIds, measureMethod);
				//chargedCount = ticketInfoService.countCharged4All(appInst.getId(), measureMethod);
				//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeMode(appInst.getId(), measureMethod);
			}else if(PricingInfo.IMcType.MONTH_BASED.equals(mcType)){
				Date _start = DateUtils.getFirstDayOfMonth(today);
				if(_start.before(effDate)){
					_start = effDate;
				}
				Date _end = DateUtils.getLastDayOfMonth(today);
				//2015-04 产品包 获取ticketInfos
				chargedCount = ticketInfoService.countCharged4Between(appInstIds, measureMethod, _start, _end);
				unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, _start, _end);
				//chargedCount = ticketInfoService.countCharged4Between(appInst.getId(), measureMethod, _start, _end);
				//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, _start, _end);
			}else if(PricingInfo.IMcType.YEAR_BASED.equals(mcType)){
				Date _start = DateUtils.addYear(effDate, DateUtils.getIntervalDays(effDate, today));
				Date _end = today;
				//2015-04 产品包 获取ticketInfos
				chargedCount = ticketInfoService.countCharged4Between(appInstIds, measureMethod, _start, _end);
				unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInstIds, measureMethod, _start, _end);
				//chargedCount = ticketInfoService.countCharged4Between(appInst.getId(), measureMethod, _start, _end);
				//unchargedTickekList = ticketInfoService.findUnchargedTicketInfoByAppInstAndChargeModeAndCreatedTimeBetween(appInst.getId(), measureMethod, _start, _end);
			}else{
				throw new UnsupportedOperationException("非法的计量统计方式，阶梯型计算方式只支持全部、按月、按年统计！");
			}
			List<TariffSnapshot> tariffSnapList = pricingInfoSnap.getTariffList();
			if(unchargedTickekList != null && unchargedTickekList.size()>0){
				for(TicketInfo ticketInfo : unchargedTickekList){
					long chargeOrder = chargedCount + 1;
					double uPrice = getPrice4Trap(tariffSnapList, chargeOrder);
					createBillingList(user, chargingItemDetail, prodInst, pricingInfoSnap.getAcctItemType(),
							BillingList.Type.PRE_USAGE, uPrice, null, ticketInfo, null, null);
					ticketInfoService.markCharged(ticketInfo.getId(), chargeOrder);
					chargedCount++ ;
				}
				chargingItemDetailService.changeLastChargingTime(chargingItemDetail.getId(), DateUtils.getCurrentTimestamp());
			}
		}else{
			throw new UnsupportedOperationException("非法的计费模式，使用量计费不支持离散型计算方法！");
		}
	}

	private double getPrice4Trap(List<TariffSnapshot> tariffList, long order){
		double result = 0.00;
		Collections.sort(tariffList, new Comparator<TariffSnapshot>() {
			@Override
			public int compare(TariffSnapshot o1, TariffSnapshot o2) {
				int startRate1 = o1.getStartRate().intValue();
				int startRate2 = o2.getStartRate().intValue();
				if(startRate1 > startRate2){
					return 1;
				}else if(startRate1 == startRate2){
					return 0;
				}else{
					return -1;
				}
			}
		});
		for(TariffSnapshot tariff : tariffList){
			int start = tariff.getStartRate().intValue();
			int end = (tariff.getEndRate() == null) ? Integer.MAX_VALUE : tariff.getEndRate().intValue();
			int measureRate = tariff.getMeasureRate().intValue();
			if(start < order && order <= end){
				result = tariff.getFixedPrice()/measureRate;
				return result;
			}
		}
		return result;
	}
}
